using System;
using System.Collections.Generic;
using System.Text;
using AlgorithmsVisualized.Controls;

namespace DijkstraDemo1
{
    #region Comments
    /*public class Graph : IGraph
    {
        #region IGraph Members

        public bool IsWeighted
        {
            get
            {
                return true;
            }
            set
            { }
        }

        public bool IsDirected
        {
            get
            {
                return true;
            }
            set
            { }
        }

        public List<Edge> Edges
        {
            get
            {
                return _edges;
            }
            set
            {
                _edges = value;
            }
        }

        public List<Node> Nodes
        {
            get
            {
                return _nodes;
            }
            set
            {
                _nodes = value;
            }
        }

        #endregion

        #region IEnumerable<IStep> Members

        public IEnumerator<IStep> GetEnumerator()
        {
            
        }

        #endregion

        #region IEnumerable Members

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
        public void Insert(Node n)
        {
            Nodes.Add(n);
        }
    }*/
    #endregion
    public class DijkstraEnumrator : IEnumerator<IStep>
    {
        IStep step;
        #region IEnumerator<IStep> Members

        public IStep Current
        {
            get { return step; }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            
        }

        #endregion

        #region IEnumerator Members

        object System.Collections.IEnumerator.Current
        {
            get { throw new Exception("The method or operation is not implemented."); }
        }

        public bool MoveNext()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        public void Reset()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
    public class DijkStep : IStep
    {
        #region IStep Members

        public bool IsFinal
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        public IGraph State
        {
            get
            {
                throw new Exception("The method or operation is not implemented.");
            }
            set
            {
                throw new Exception("The method or operation is not implemented.");
            }
        }

        #endregion
    }
    public class Graph : IGraph
    {
        internal class GraphEnumerated : IEnumerator <IStep>
        {
            SortedDictionary<Node, Node> Q;
            Graph g;
            Node n;
            int i;

            public GraphEnumerated(Graph G)
            {
                g = G;
            }

            #region IEnumerator Members

            public object Current
            {
                get { return null; }

            }

            public bool MoveNext()
            {
                if (Q == null || Q.Count == 0)
                    return false;
                if (i >= n.Adj.Count)
                {
                    foreach (Node Key in Q.Keys)
                    {
                        n = Key;
                        break;
                    }

                    Q.Remove(n);
                    i = 0;
                }
                if (n.Adj.Count <= 0)
                    return true;
                Arrow d = n.Adj[i];
                if (!g.isPrim && d.n2.Destination > n.Destination + d.Weight ||
                    g.isPrim && Q.ContainsKey(d.n2) && d.n2.Destination > d.Weight)
                {
                    Q.Remove(d.n2);
                    d.n2.Parent = n;
                    if (g.isPrim)
                        d.n2.Destination = d.Weight;
                    else
                        d.n2.Destination = n.Destination + d.Weight;

                    Q.Add(d.n2, null);
                    d.n2.inPath = true;
                    if (g.parent != null)
                        g.parent.Invalidate();
                }
                i++;
                return true;
            }

            public void Reset()
            {
                {
                    foreach (Node n in g.NList)
                    {
                        n.Destination = int.MaxValue;
                        n.Parent = null;
                    }
                    g.NList[g.src - 1].Destination = 0;
                    Q = new SortedDictionary<Node, Node>();
                    foreach (Node n in g.NList)
                        Q.Add(n, null);
                }
                foreach (Node Key in Q.Keys)
                {
                    n = Key;
                    break;
                }
                //				this.n = Q.Keys[0];
                Q.Remove(this.n);
                i = 0;
            }

            #endregion

            #region IEnumerator<IStep> Members

            IStep IEnumerator<IStep>.Current
            {
                get { return null; }
            }

            #endregion

            #region IDisposable Members

            public void Dispose()
            {
            }

            #endregion
        }
        public bool isPrim = false;
        public int tout = 1000;
        public int src = 1, destination = 3;
        //Control parent;
        public Node[] NList;
        public Graph(int size)
        {
            NList = new Node[size];

            for (int i = 0; i < size; i++)
            {
                //                NList[i] = new Node();
                //              NList[i].ID = i+1;
            }
            //parent = P;
        }

        public void AddLink(int from, Edge ar)
        {
            NList[from - 1].AddLink(ar);
        }
        public void AddLink(int from, int to, int weight)
        {
            //NList[from - 1].AddLink(new NList[to - 1], weight);
        }
        public void DijkstraMT(object obj)
        {
            Dijkstra(1, 3);
        }
        public void Dijkstra(int src, int destination)
        {
            this.src = src;
            this.destination = destination;
            return;
            foreach (Node n in NList)
            {
                n.Value = int.MaxValue;
                n.Parent = null;
            }
            NList[src - 1].Destination = 0;
            SortedDictionary<Node, Node> Q = new SortedDictionary<Node, Node>();
            foreach (Node n in NList)
                Q.Add(n, null);
            while (Q.Count != 0)
            {
                Node n;
                foreach (Node key in Q.Keys)
                {
                    n = key;
                    break;
                }
                Q.Remove(n);
                foreach (Arrow d in n.Adj)
                    if (d.n2.Destination > n.Destination + d.Weight)
                    {
                        Q.Remove(d.n2);
                        d.n2.Parent = n;
                        d.n2.Destination = n.Destination + d.Weight;
                        d.n2.inPath = true;

                        Q.Add(d.n2, null);
                        d.ReDraw();
                        Application.DoEvents();
                        //						Thread.CurrentThread.Suspend();
                        if (parent != null)
                            parent.Invalidate();
                        //                        Thread.Sleep(tout);
                    }
            }
        }

        #region IEnumerable Members

        public System.Collections.IEnumerator GetEnumerator()
        {
            IEnumerator ie = new GraphEnumerated(this);
            ie.Reset();
            return ie;
        }

        #endregion
        #region IGraph
        public bool IsWeighted
        {
            get
            {
                return true;
            }
            set
            { }
        }

        public bool IsDirected
        {
            get
            {
                return true;
            }
            set
            { }
        }

        public List<Edge> Edges
        {
            get
            {
                return _edges;
            }
            set
            {
                _edges = value;
            }
        }

        public List<Node> Nodes
        {
            get
            {
                return _nodes;
            }
            set
            {
                _nodes = value;
            }
        }

        #endregion

        #region IEnumerable<IStep> Members

        IEnumerator<IStep> IEnumerable<IStep>.GetEnumerator()
        {
            throw new Exception("The method or operation is not implemented.");
        }

        #endregion
    }
}
